home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / c_chest.arc / DEMOMENU.C < prev    next >
Text File  |  1990-10-12  |  15KB  |  465 lines

  1. /*    DEMOMENU.C
  2.  
  3.  
  4.  This C Language Light Bar Menu Source Code was Produced
  5.  Using The CPOP(C) Light Bar Menu C Source Code Generator
  6.  Copyright by Bill Buckels 1989, 1990
  7.  
  8. This Source File Format was developed using Mix Power C Version 2.0
  9. and Has also Been Tested With Varying Degrees of Success
  10. With Turbo C Version 2.01, Quick C Version 1.01 and Microsoft C Version 5.1
  11.  
  12. Fix-ups required for use with Turbo.(AHEM!)
  13.  
  14. Turbo C Has a Problem With The Dos Services Component,
  15. and does Garbage although the routine still shells Command.
  16. This is a problem that is not shared with the other C's,
  17. nor is the fact that malloc.h is not part of Turbo's Stable.
  18. Since Turbo C is the "ODD MAN OUT" on these, I have decided to leave
  19. Things The Way they are rather than diddle with Conditionals.
  20.  
  21.  This Code was developed from the PopUp Menu Template
  22.  Supplied with  Mix Power C.
  23.  
  24.  
  25.  Bill Buckels, Starving Programmer
  26.  982 Hector Avenue
  27.  Winnipeg, Manitoba, Canada R3M 2G6
  28.  
  29.  (204) 452-2815
  30.  
  31. */
  32.  
  33. #include <stdio.h>
  34. #include <bios.h>
  35. #include <dos.h>
  36. #include <malloc.h>
  37. #include <stdlib.h>  /* declares system function  */
  38. #include <string.h>  /* declares strlen function  */
  39.  
  40.  
  41. #define CRTWIDTH   80     /* width of the CRT  (in characters) */
  42. #define CRTHEIGHT  25     /* height of the CRT (in characters) */
  43. #define ENTERKEY   '\x0d' /* character generated by the Enter key */
  44. #define ESCKEY     '\x1b' /* character generated by the Esc key */
  45. #define FUNCKEY    '\x00' /* first character generated by function keys */
  46. #define HOMEKEY    'G'    /* second character generated by Home key */
  47. #define ENDKEY     'O'    /* second character generated by End key */
  48. #define UPARROW    'H'    /* second character generated by up-arrow key */
  49. #define DOWNARROW  'P'    /* second character generated by down-arrow key */
  50. #define MA         0xb000 /* start of video memory for Monochrome Adapter */
  51. #define CGA        0xb800 /* start of video memory for Color Graphics Adapter */
  52.  
  53. struct video_bytes {
  54.     unsigned char  ch;    /* character value of video word */
  55.     unsigned char  attr;  /* attribute value of video word */
  56. };
  57.  
  58. union video_word {
  59.     struct video_bytes byte;
  60.     int word;
  61. };
  62.  
  63.  
  64. #undef MK_FP
  65. #undef poke
  66. #undef peek
  67.  
  68. /* undefine the above if they exist      */
  69. /* all compilers start on equal footing  */
  70.  
  71. /* macros to poke into memory */
  72. /* dynamically cast a far pointer from segment and offset info */
  73. #define MK_FP(seg,off) ((char far *)(((long)(seg) << 16) | (off)))
  74. /* write an integer at a memory location */
  75. #define poke(a,b,c) (*((int  far*)MK_FP((a),(b))) = (int)(c))
  76. /* read an integer */
  77. #define peek(a,b)   (*((int  far*)MK_FP((a),(b))))
  78.  
  79. unsigned int bionicequip()
  80. {
  81.    union REGS inregs, outregs;
  82.  
  83.    int86(0x11,&inregs, &outregs);
  84.    return outregs.x.ax;
  85.  
  86. }
  87.  
  88. void cls(int BACK,int FRONT)
  89. {
  90.     union REGS reg;
  91.  
  92.     reg.h.ah = 6;
  93.     reg.h.al = 0;
  94.     reg.h.ch = 0;
  95.     reg.h.cl = 0;
  96.     reg.h.dh = 24;
  97.     reg.h.dl = 79;
  98.     reg.h.bh = (BACK << 4) + FRONT;
  99.     int86(0x10, ®, ®);
  100. }
  101.  
  102. int crow()
  103. {
  104.     union REGS inregs,outregs;
  105.     inregs.h.ah = 3;
  106.     inregs.h.bh = 0;
  107.     int86(0x10, &inregs,&outregs);
  108.     return outregs.h.dh;
  109. }
  110.  
  111. void pcurs(row, col)
  112.    int row,col;
  113. {
  114.    union REGS reg;
  115.  
  116.    reg.h.ah = 2;
  117.    reg.h.bh = 0;
  118.    reg.h.dh = row;
  119.    reg.h.dl = col;
  120.    int86(0x10, ®,®);
  121. }
  122.  
  123.  
  124. int popup(int row, int col, char *menu[])
  125. {
  126.     /* display a popup menu (menu[0] .. menu[n])
  127.        within a window located at the screen position
  128.        specified by row and col.  Use the up-arrow and
  129.        down-arrow keys to position the cursor.  Press
  130.        the enter key to select the option under the
  131.        cursor.
  132.  
  133.        Returns: 0 if menu[0] selected
  134.                 1 if menu[1] selected
  135.                     ...
  136.                -1 if Esc key pressed                */
  137.  
  138.     int c, i, j, length, address, segment, offset, offset2;
  139.     char NORMAL = '\x07' ;/* attribute for normal video */
  140.     char REVERSE = '\x70' ;/* attribute for reverse video */
  141.     char INTENSE = '\x0e' ;/* attribute for high intensity video */
  142.     int currow, maxrow, minrow;
  143.     int choice, bwidth, bheight, width = 0, height = 0;
  144.     int *buffer, *bufptr;
  145.     char *strptr, *strptr2, *(*hotkey)[];
  146.     union video_word video;
  147.  
  148.     /* set video segment for Monochrome or Color Graphics Adaptor */
  149.     if ((bionicequip() & 0x30) == 0x30) segment = MA;
  150.     else { segment = CGA;
  151.            NORMAL = '\x17' ;/* attribute for normal video */
  152.            REVERSE = '\x02' ;/* attribute for reverse video */
  153.            INTENSE = '\x1e' ;/* attribute for high intensity video */
  154.            }
  155.  
  156.     /* calculate address of row and col */
  157.     address = (row * CRTWIDTH * 2) + (col * 2);
  158.  
  159.     /* calculate width and height of menu window */
  160.     for (i=0; menu[i] != NULL; i++) {
  161.         length = strlen(menu[i]);
  162.         if (length > width) width = length;
  163.         height++;
  164.     } /* width and height must be greater than 0 */
  165.     if (width == 0 || height == 0) {
  166.         printf("\n*** popup function: invalid menu argument ***\n");
  167.         exit(0);
  168.     }
  169.  
  170.     /* allow for a border around the text */
  171.     bwidth = width + 2;
  172.     bheight = height + 2;
  173.     /* eliminate rightmost and/or bottom portion of window if too large */
  174.     if (bwidth > CRTWIDTH - col) {
  175.         bwidth = CRTWIDTH - col;
  176.         width = bwidth - 2;
  177.     }
  178.     if (bheight > CRTHEIGHT - row) {
  179.         bheight = CRTHEIGHT - row;
  180.         height = bheight - 2;
  181.     }
  182.     /* window must be at least 3 x 3 */
  183.     if ((bwidth < 3) || (bheight < 3)) {
  184.         printf("\n*** popup function: invalid row or col argument ***\n");
  185.         exit(0);
  186.     }
  187.  
  188.  
  189.     /* allocate buffer for saving area of screen beneath popup
  190.        and array of hotkey characters */
  191.     buffer = calloc(bwidth * bheight, 2);
  192.     hotkey = calloc(height, sizeof(char *));
  193.     if ((buffer == NULL) || hotkey == NULL) {
  194.         printf("\n*** popup function: out of memory ***\n");
  195.         exit(0);
  196.     }
  197.  
  198.     /* make the first uppercase character in each line of
  199.         the menu a hotkey */
  200.     for (i=0; i < height; i++)
  201.         (*hotkey)[i] = strpbrk(menu[i], "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  202.  
  203.     /* save area of screen that will be modified */
  204.     currow = address;
  205.     bufptr = buffer;
  206.     for (i = 0; i < bheight; i++) {
  207.         offset = currow;
  208.         for (j = 0; j < bwidth; j++) {
  209.             *bufptr++ = peek(segment, offset);
  210.             offset += 2;
  211.         }
  212.         currow += (CRTWIDTH * 2);
  213.     }
  214.  
  215.     /* draw menu outline */
  216.     video.byte.attr = INTENSE;
  217.     offset = address;
  218.     video.byte.ch = '\xc9';                 /* upper left corner */
  219.     poke(segment, offset, video.word);
  220.     offset += (bwidth - 1) * 2;
  221.     video.byte.ch = '\xbb';                 /* upper right corner */
  222.     poke(segment, offset, video.word);
  223.     offset = address + (bheight - 1) * CRTWIDTH * 2;
  224.     video.byte.ch = '\xc8';                 /* lower left corner */
  225.     poke(segment, offset, video.word);
  226.     offset += (bwidth - 1) * 2;
  227.     video.byte.ch = '\xbc';                 /* lower right corner */
  228.     poke(segment, offset, video.word);
  229.     offset = address + 2;
  230.     offset2 = offset + (bheight - 1) * CRTWIDTH * 2;
  231.     video.byte.ch = '\xcd';                 /* horizontal lines */
  232.     for (i = 0; i < width; i++) {
  233.         poke(segment, offset, video.word);
  234.         offset += 2;
  235.         poke(segment, offset2, video.word);
  236.         offset2 += 2;
  237.     }
  238.     offset = address + CRTWIDTH * 2;
  239.     offset2 = offset + (bwidth - 1) * 2;
  240.     video.byte.ch = '\xba';                 /* vertical lines */
  241.     for (i = 0; i < height; i++) {
  242.         poke(segment, offset, video.word);
  243.         offset += CRTWIDTH * 2;
  244.         poke(segment, offset2, video.word);
  245.         offset2 += CRTWIDTH * 2;
  246.     }
  247.  
  248.     /* fill in menu text */
  249.     minrow = address + (CRTWIDTH * 2) + 2;
  250.     currow = minrow;
  251.     video.byte.attr = REVERSE;
  252.     for (i = 0; i < height; i++) {
  253.         strptr = menu[i];
  254.         offset = currow;
  255.         for (j = 0; j < width; j++) {
  256.             if (*strptr == '\0') video.byte.ch = ' ';
  257.             else {
  258.                 if (i != 0 && strptr == (*hotkey)[i])
  259.                     video.byte.attr = INTENSE;
  260.                 video.byte.ch = *strptr++;
  261.             }
  262.             poke(segment, offset, video.word);
  263.             offset += 2;
  264.             if (video.byte.attr == INTENSE)
  265.                 video.byte.attr = NORMAL;
  266.         }
  267.         video.byte.attr = NORMAL;
  268.         maxrow = currow;
  269.         currow += (CRTWIDTH * 2);
  270.     }
  271.  
  272.     /* get menu choice */
  273.     currow = minrow;
  274.     choice = 0;
  275.     c = getch();
  276.     while ((c != ENTERKEY) && (c != ESCKEY)) {
  277.         if (c == FUNCKEY) {
  278.             c = getch(); /* get second character of key */
  279.             j = choice;
  280.             offset = currow;
  281.             strptr = menu[choice];
  282.             switch (c) {
  283.  
  284.                 case HOMEKEY:
  285.                     currow = minrow;
  286.                     choice = 0;
  287.                     break;
  288.  
  289.                 case ENDKEY:
  290.                     currow = maxrow;
  291.                     choice = height - 1;
  292.                     break;
  293.  
  294.                 case DOWNARROW:
  295.                     if (currow == maxrow) {
  296.                         currow = minrow;
  297.                         choice = 0;
  298.                     }
  299.                     else {
  300.                         currow += CRTWIDTH * 2;
  301.                         choice++;
  302.                     }
  303.                     break;
  304.  
  305.                 case UPARROW:
  306.                     if (currow == minrow) {
  307.                         currow = maxrow;
  308.                         choice = height - 1;
  309.                     }
  310.                     else {
  311.                         currow -= CRTWIDTH * 2;
  312.                         choice--;
  313.                     }
  314.                     break;
  315.  
  316.                 default:
  317.                     c = getch();
  318.                     continue;
  319.             }
  320.             offset2 = currow;
  321.             strptr2 = menu[choice];
  322.             for (i = 0; i < width; i++) {
  323.                 video.byte.attr = NORMAL;
  324.                 if (*strptr == '\0') video.byte.ch = ' ';
  325.                 else {
  326.                     if (strptr == (*hotkey)[j])
  327.                         video.byte.attr = INTENSE;
  328.                     video.byte.ch = *strptr++;
  329.                 }
  330.                 poke(segment, offset, video.word);
  331.                 offset += 2;
  332.                 if (*strptr2 == '\0') video.byte.ch = ' ';
  333.                 else video.byte.ch = *strptr2++;
  334.                 video.byte.attr = REVERSE;
  335.                 poke(segment, offset2, video.word);
  336.                 offset2 += 2;
  337.             }
  338.             c = getch();
  339.         }
  340.         else {
  341.             for (i = 0; i < height; i++) {
  342.                 if (toupper(c) == *((*hotkey)[i])) {
  343.                     choice = i;
  344.                     break;
  345.                 }
  346.             }
  347.             if (i < height) break;
  348.             else c = getch();
  349.         }
  350.     }
  351.  
  352.     /* restore saved screen area beneath popup menu */
  353.     currow = address;
  354.     bufptr = buffer;
  355.     for (i = 0; i < bheight; i++) {
  356.         offset = currow;
  357.         for (j = 0; j < bwidth; j++) {
  358.             poke(segment, offset, *bufptr++);
  359.             offset += 2;
  360.         }
  361.         currow += (CRTWIDTH * 2);
  362.     }
  363.  
  364.     /* free the allocated memory */
  365.     free(buffer);
  366.     free(hotkey);
  367.  
  368.     /* return the menu choice */
  369.     if (c == ESCKEY) return -1;
  370.     else return choice;
  371. }
  372.  
  373.  
  374.  
  375. char *menu[] = {
  376.  
  377.    "                      Dos Services                      ",/*  choice  0  */
  378.    "           The Chuck and Patty Graphics Demo            ",/*  choice  1  */
  379.    " Dark Humour - The Confusing World of Computer Language ",/*  choice  2  */
  380.    "         SATAN C COMPILER - A Programmer's Saga         ",/*  choice  3  */
  381.    "          George Does Iran - Musical Interlude          ",/*  choice  4  */
  382.    "         Odie and Garfield... Not In The Least...       ",/*  choice  5  */
  383.    "           A Sorted PCX and BSAVED Image Viewer         ",/*  choice  6  */
  384.                                       NULL         };      /* terminator */
  385.  
  386. char *command[] ={
  387.    "",             /*  command 0  */
  388.    "PEANUTS.EXE",  /*  command 1  */
  389.    "LANGUAGE.EXE", /*  command 2  */
  390.    "DEVIL.EXE",    /*  command 3  */
  391.    "GULFBILL.EXE", /*  command 4  */
  392.    "GARFIELD.EXE", /*  command 5  */
  393.    "PBVIEW.EXE",   /*  command 6  */
  394.     NULL         };      /* terminator */
  395.  
  396.  
  397. void end_program(int prompt_origin)
  398. {
  399.     pcurs(prompt_origin,0);
  400.     exit(0);
  401. }
  402.  
  403. void dos_services(void)
  404. {
  405.     char input[81]; /* width of the crt                     */
  406.                     /* actual dos buffer is 128 characters  */
  407.     int status;
  408.  
  409.            {
  410.     cls(0,14);
  411.     pcurs(0,0);
  412.     if (system(NULL)){
  413.             printf("\n\t<<<  Enter a Command or Press ");
  414.             printf("Return For Dos Shell  >>>\n");
  415.         gets(input);
  416.         if (strlen(input)==0){
  417.             printf("\t<<<        type EXIT to return to ");
  418.             printf("the Menu          >>>\n\n");
  419.             }
  420.         status = system(input);
  421.         if (status == 0){
  422.             printf("\n\n\t<<<    Pausing...Press any Key ");
  423.             printf("to return to Menu    >>>");
  424.             }
  425.         else{
  426.             printf("\n\n\t<<<   Dos Error %d. ",status);
  427.             printf("Press any Key ...   >>>\n\n");
  428.             }
  429.             }
  430.    else {   printf("\n\n\t<<<     Command.Com not ");
  431.             printf("found.  Press any Key.      >>>\n\n");   }
  432.             }
  433.    getch();
  434.  cls(0,7);
  435. }
  436. main()
  437. {
  438.     int i, choice, status, prompt_origin=(crow());
  439.  
  440.     start:
  441.          pcurs(26,0);
  442.  
  443.  
  444.         choice = popup(10,10, menu);
  445.         switch (choice){
  446.             case  -1:  end_program(prompt_origin);
  447.             case  0 :  prompt_origin=0;dos_services();break;
  448.  
  449.             default :   {
  450.                          pcurs(0,0);
  451.                          if (strlen(command[choice])==0){
  452.                                      break;
  453.                                     }
  454.                          status = system(command[choice]);
  455.                          if (status ==0){
  456.                                          break;
  457.                                         }
  458.                         }
  459.             }
  460.      goto start;
  461. }
  462.  
  463.  
  464.  
  465.